package produto.manager;

import geral.manager.GenericManager;
import geral.manager.UtilManager;
import geral.util.FacesUtil;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Inject;
import javax.inject.Named;

import br.com.sgc.entities.produto.ComposicaoProduto;
import br.com.sgc.entities.produto.ProdutoComposto;
import br.com.sgc.entities.produto.ProdutoFinal;
import br.com.sgc.entities.rh.Funcionario;
import br.com.sgc.exception.ValidacaoException;
import br.com.sgc.session.GenericSession;

@Named
@ConversationScoped
public class ComposicaoProdutoManager extends GenericManager implements Serializable {

	private static final long serialVersionUID = -5425385093912991767L;
	
	@EJB private GenericSession<ComposicaoProduto> composicaoSession;
	
	@EJB private GenericSession<ProdutoComposto> produtoCompostoSession;
	
	@Inject UtilManager utilManager;
	
	private ComposicaoProduto composicao = new ComposicaoProduto();
	
	private List<ComposicaoProduto> list = new ArrayList<ComposicaoProduto>();
	
	private List<ProdutoFinal> produtos = new ArrayList<ProdutoFinal>();
	
	private ProdutoFinal produto = new ProdutoFinal();
	
	private List<ProdutoComposto> listProdutoComposto = new ArrayList<ProdutoComposto>();
	
	private ProdutoComposto produtoComposto = new ProdutoComposto();
	
	private Funcionario funcionario = new Funcionario();
	
	private Boolean showPanelCadastro = false;
	
	private Boolean referenciaProduto = true;
	
	private Boolean maoDeObra = false;
	
	public String list(){
		showPanelCadastro = false;
		referenciaProduto = true;
		maoDeObra = false;
		list = composicaoSession.findAll(ComposicaoProduto.class, utilManager.getSegurancaManager().getUsuarioLogado().getClinica().getId());
		return "formComposicaoProduto";
	}
	
	
	public String prepareSave(){
		produtos = utilManager.getProdutoManager().getProdutoSession().findAll(ProdutoFinal.class, utilManager.getSegurancaManager().getUsuarioLogado().getClinica().getId());
		composicao = new ComposicaoProduto();
		listProdutoComposto = new ArrayList<ProdutoComposto>();
		produtoComposto = new ProdutoComposto();
		showPanelCadastro = true;
		referenciaProduto = true;
		maoDeObra = false;
		return "formComposicaoProduto";
	}
	
	public String prepareUpdate(){
		produtos = utilManager.getProdutoManager().getProdutoSession().findAll(ProdutoFinal.class, utilManager.getSegurancaManager().getUsuarioLogado().getClinica().getId());
		composicao = composicaoSession.findById(ComposicaoProduto.class, composicao.getId(), true);
		listProdutoComposto = new ArrayList<ProdutoComposto>();
		produtoComposto = new ProdutoComposto();
		
		for(ProdutoComposto pc: composicao.getProdutoComposto()){
			listProdutoComposto.add(produtoCompostoSession.findById(ProdutoComposto.class, pc.getId(), true));
		}
		showPanelCadastro = true;
		referenciaProduto = true;
		maoDeObra = false;
		return "formComposicaoProduto";
	}
	
	public String save(){
		try {
			composicao.setProdutoComposto(listProdutoComposto);
			composicao.setClinica(utilManager.getSegurancaManager().getUsuarioLogado().getClinica());
			composicao.setTipoProduto(null);
			composicaoSession.save(composicao);
			FacesUtil.mensInfo("Composição de Produtos salva com sucesso");
			return list();
			
		} catch (ValidacaoException e) {
			FacesUtil.mensErro(e.getMessage());
			e.printStackTrace();
		}
		return null;
	}
	
	public String update(){
		try {
			if(listProdutoComposto.isEmpty()){
				composicao.setValorCustoTotalProdutoComposto(new BigDecimal(0.0));
				composicao.setValorVenda(new BigDecimal(0.0));
			}
			composicao.setProdutoComposto(listProdutoComposto);
			composicao.setClinica(utilManager.getSegurancaManager().getUsuarioLogado().getClinica());
			composicaoSession.update(composicao);
			FacesUtil.mensInfo("Composição de Produtos atualizada com sucesso");
			return list();
			
		} catch (ValidacaoException e) {
			FacesUtil.mensErro(e.getMessage());
			e.printStackTrace();
		}
		return null;
	}
	
	public void addProdutoComposto(){
		if(produto != null && produto.getId() != null){
			produto = utilManager.getProdutoManager().getProdutoSession().findById(ProdutoFinal.class, produto.getId());
			produtoComposto.setProduto(produto);
			produtoComposto.setNomeProdutoComposto(produto.getDescricao());
			produtoComposto.setValorProduto(produto.getValorVenda());
		} else {
			produtoComposto.setProduto(null);  
		}
		if(produtoComposto.getUtilizaMaoDeObra() != null && produtoComposto.getUtilizaMaoDeObra()){
			funcionario = utilManager.getFuncionarioManager().getFuncionarioSession().findById(Funcionario.class, funcionario.getId(), true);
			produtoComposto.setValorProduto(funcionario.getProventos().getCustoEfetivoTotalHora());
		}
		
		produtoComposto.setValorProduto(produtoComposto.getValorProduto().multiply(produtoComposto.getQuantidadeProduto()));
		produtoComposto.getValorProduto().setScale(2, RoundingMode.HALF_UP);
		produtoComposto.setComposicao(composicao);
		
		if(composicao.getProdutoComposto() == null){
			composicao.setProdutoComposto(new ArrayList<ProdutoComposto>());
		}
		
		calcularValorVendaComposicao();
		
		listProdutoComposto.add(produtoComposto);
		produtoComposto = new ProdutoComposto();
		produto = new ProdutoFinal();
	}
	
	public void removeProdutoComposto(){
		if(produtoComposto.getId() != null){
			produtoComposto = produtoCompostoSession.findById(ProdutoComposto.class, produtoComposto.getId());
			produtoComposto.setComposicao(null);
			try {
				produtoCompostoSession.update(produtoComposto);
			} catch (ValidacaoException e) {
				e.printStackTrace();
				return;
			}
		}
		
		listProdutoComposto.remove(produtoComposto);
		if(listProdutoComposto.isEmpty()){
			composicao.setValorVenda(new BigDecimal(0.0));
		}
		removerValorVendaComposicao();
		
		produtoComposto = new ProdutoComposto();
		produto = new ProdutoFinal();
		
	}


	private void removerValorVendaComposicao() {
		BigDecimal valor = produtoComposto.getValorProduto();
		
		if(composicao.getValorCustoTotalProdutoComposto() == null){
			composicao.setValorCustoTotalProdutoComposto(new BigDecimal(0.0));
		}
		composicao.setValorCustoTotalProdutoComposto(composicao.getValorCustoTotalProdutoComposto().subtract(valor));
		if(composicao.getValorCustoTotalProdutoComposto().doubleValue() < 0){
			composicao.setValorCustoTotalProdutoComposto(new BigDecimal(0.0));
		}
		
		if(composicao.getPercentualLucro() != null){
			BigDecimal lucro = composicao.getValorCustoTotalProdutoComposto().multiply(composicao.getPercentualLucro()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
			composicao.setValorVenda(composicao.getValorCustoTotalProdutoComposto().subtract(lucro));
			if(composicao.getValorVenda().doubleValue() < 0){
				composicao.setValorVenda(new BigDecimal(0.0));
			}
		}
		
	}


	private void calcularValorVendaComposicao() {
		BigDecimal valor  = produtoComposto.getValorProduto();
		if(composicao.getValorCustoTotalProdutoComposto() == null){
			composicao.setValorCustoTotalProdutoComposto(new BigDecimal(0.0));
		}
		
		composicao.setValorCustoTotalProdutoComposto(composicao.getValorCustoTotalProdutoComposto().add(valor));
		BigDecimal lucro = new BigDecimal(0.0);
		
		if(composicao.getPercentualLucro() != null){
			lucro = composicao.getValorCustoTotalProdutoComposto().multiply(composicao.getPercentualLucro()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
		}
		
		composicao.setValorVenda(composicao.getValorCustoTotalProdutoComposto().add(lucro));
	}

	public void findFuncionarios(){
		if(maoDeObra)
			utilManager.getFuncionarioManager().list();
		
			produtoComposto.setUtilizaMaoDeObra(maoDeObra);
		
	}

	public GenericSession<ComposicaoProduto> getComposicaoSession() {
		return composicaoSession;
	}

	public void setComposicaoSession(
			GenericSession<ComposicaoProduto> composicaoSession) {
		this.composicaoSession = composicaoSession;
	}

	public ComposicaoProduto getComposicao() {
		return composicao;
	}

	public void setComposicao(ComposicaoProduto composicao) {
		this.composicao = composicao;
	}

	public List<ComposicaoProduto> getList() {
		return list;
	}

	public void setList(List<ComposicaoProduto> list) {
		this.list = list;
	}

	public List<ProdutoFinal> getProdutos() {
		return produtos;
	}

	public void setProdutos(List<ProdutoFinal> produtos) {
		this.produtos = produtos;
	}

	public ProdutoFinal getProduto() {
		return produto;
	}


	public void setProduto(ProdutoFinal produto) {
		this.produto = produto;
	}


	public Boolean getShowPanelCadastro() {
		return showPanelCadastro;
	}

	public void setShowPanelCadastro(Boolean showPanelCadastro) {
		this.showPanelCadastro = showPanelCadastro;
	}


	public ProdutoComposto getProdutoComposto() {
		return produtoComposto;
	}


	public void setProdutoComposto(ProdutoComposto produtoComposto) {
		this.produtoComposto = produtoComposto;
	}


	public List<ProdutoComposto> getListProdutoComposto() {
		return listProdutoComposto;
	}


	public void setListProdutoComposto(List<ProdutoComposto> listProdutoComposto) {
		this.listProdutoComposto = listProdutoComposto;
	}


	public Boolean getReferenciaProduto() {
		return referenciaProduto;
	}


	public void setReferenciaProduto(Boolean referenciaProduto) {
		this.referenciaProduto = referenciaProduto;
	}


	public Funcionario getFuncionario() {
		return funcionario;
	}


	public void setFuncionario(Funcionario funcionario) {
		this.funcionario = funcionario;
	}


	public Boolean getMaoDeObra() {
		return maoDeObra;
	}


	public void setMaoDeObra(Boolean maoDeObra) {
		this.maoDeObra = maoDeObra;
	}

}
